using System;
using System.Collections.Generic;

namespace YouVisio.Silverlight.TextDiff
{
    public struct PartsAggregationState<TAccumulator, TSource, TPart>
    {
        // those fields must be initialized

        public IEqualityComparer<TPart> Comparer;
        public IPartsRetriever<TSource, TPart> Before;
        public IPartsRetriever<TSource, TPart> After;
        public int InitialBeforeIndex;
        public int InitialAfterIndex;
        public int Length;
        public Func<PartsAggregationInfo<TAccumulator, TSource, TPart>, PartsAggregationInfo<TAccumulator, TSource, TPart>> Function;
        public Action<PartsAggregationState<TAccumulator, TSource, TPart>> Log;
        public bool SkipToCheckIfPartExists;
        // accumulator may or may not be initialized
        public TAccumulator Accumulator;

        public void VerifyInitialization()
        {
            if (Comparer == null)
                Comparer = EqualityComparer<TPart>.Default;
            if (Before == null)
                throw new InvalidOperationException("Please specify value for Before field of the PartsAggregationState struct");
            if (After == null)
                throw new InvalidOperationException("Please specify value for After field of the PartsAggregationState struct");
            if (InitialBeforeIndex < -1)
                InitialBeforeIndex = -1;
            if (InitialAfterIndex < -1)
                InitialAfterIndex = -1;
            if (Length <= 0)
                Length = Int32.MaxValue;
            if (Function == null)
                throw new InvalidOperationException("Please specify value for Function field of the PartsAggregationState struct");
            if (Log == null)
                Log = s => { };
        }



        // those fields are set by the algorithm
        public int LastMatchBeforeIndex;
        public int LastMatchAfterIndex;
        public int CurrentBeforeIndex;
        public int CurrentAfterIndex;
        public int MaxBeforeIndex;
        public int MaxAfterIndex;
        public TPart BeforeValue;
        public TPart AfterValue;
        public bool AreEqual;
    }
}